﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	public class HyCalcPipe
	{
		public HyCalcPipe()
		{
			this.pipes = new List<PipeLine>();
			this.valves = new List<ValveAndFitting>();
			this.FrictionFix = 1.0;
			this.ShockFix = 1.0;
		}

		public HyCalcPipe(IList<PipeLine> pipe, IList<ValveAndFitting> vfs)
		{
			this.pipes = pipe;
			this.valves = vfs;
			this.dn = pipe[0].DN;
		}

		public List<Element> Elements
		{
			get
			{
				return this.GetAllElement();
			}
		}

		public int Index
		{
			get
			{
				return this.index;
			}
			set
			{
				this.index = value;
			}
		}

		public string Name { get; set; }

		public SearchNode EndNode { get; set; }

		public IList<PipeLine> PipesLines
		{
			get
			{
				return this.pipes;
			}
		}

		public IList<ValveAndFitting> Valves
		{
			get
			{
				return this.valves;
			}
		}

		public int DN
		{
			get
			{
				return this.dn;
			}
			set
			{
				this.dn = value;
				foreach (PipeLine pipeLine in this.pipes)
				{
					pipeLine.DN = this.dn;
				}
			}
		}

		public double Resistance { get; set; }

		public double FrictionFix { get; set; }

		public double ShockFix { get; set; }

		public double Flow { get; set; }

		public double Length { get; set; }

		public double Velocity { get; set; }

		public double ResCoefLocal { get; set; }

		public double Resistancey { get; set; }

		public double Resistancej { get; set; }

		public double Rm { get; set; }

		public double Density { get; set; }

		public double PressDynamic { get; set; }

		public void Add(PipeLine pipe)
		{
			this.pipes.Add(pipe);
			this.flow = pipe.Flow;
			this.dn = pipe.DN;
		}

		public void Add(ValveAndFitting vf)
		{
			this.valves.Add(vf);
		}

		public void SetFix(HYHeatingSystemOption option)
		{
			this.ShockFix = option.ShockFix;
			this.FrictionFix = option.FrictionFix;
		}

		public bool GetAllParam()
		{
			bool result;
			try
			{
				if (this.pipes.Count == 0)
				{
					result = false;
				}
				else
				{
					this.pipes.ForEach(delegate(PipeLine pl)
					{
						this.dn = pl.DN;
						this.Velocity = pl.Velocity;
						this.Flow = pl.Flow;
						this.Rm = pl.ResistanceFrict;
						this.PressDynamic = pl.PressDynamic;
					});
					this.Resistancey = this.pipes.Sum((PipeLine pl) => pl.Resistance);
					this.Resistancey *= this.FrictionFix;
					this.Length = this.pipes.Sum((PipeLine pl) => pl.Length);
					this.ResCoefLocal = this.valves.Sum((ValveAndFitting v) => v.ResCoefLocal);
					this.Resistancej = this.valves.Sum((ValveAndFitting v) => v.ResistanceLocal);
					this.Resistancej += this.ResCoefLocal * this.PressDynamic;
					this.Resistancej *= this.ShockFix;
					this.Resistance = this.Resistancej + this.Resistancey;
					result = true;
				}
			}
			catch (Exception ex)
			{
				Log.Error(new string[]
				{
					"error:" + ex.StackTrace
				});
				result = false;
			}
			return result;
		}

		public void BackRevit()
		{
			this.pipes.ForEach(delegate(PipeLine pl)
			{
				pl.BackRevit();
			});
		}

		private bool Contains(IList<ValveAndFitting> vfs, ValveAndFitting vf)
		{
			return (from valveAndFitting in vfs
			select valveAndFitting.Id).ToList<ElementId>().Contains(vf.Id);
		}

		private bool Contains(IList<PipeLine> pls, PipeLine pl)
		{
			return (from p in pls
			select p.Id).ToList<ElementId>().Contains(pl.Id);
		}

		private List<Element> GetAllElement()
		{
			List<Element> list = (from pipeLine in this.pipes
			select pipeLine.Element).Cast<Element>().ToList<Element>();
			list.AddRange(from valveAndFitting in this.valves
			select valveAndFitting.Element);
			return list;
		}

		private IList<PipeLine> pipes;

		private IList<ValveAndFitting> valves;

		private double flow;

		private int dn;

		private int index = 1;
	}
}
